package com.atguigu.gulimail.auth.controller;

import com.atguigu.common.constant.AuthServerConstant;
import com.atguigu.common.utils.R;
import com.atguigu.gulimail.auth.feign.MemberFeign;
import com.atguigu.gulimail.auth.feign.SmsFeign;
import com.atguigu.gulimail.auth.vo.UserRegistVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Controller
public class RegController {

    @Autowired
    SmsFeign smsFeign;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MemberFeign memberFeign;

    @ResponseBody
    @GetMapping("/sms/sendCode")
    public R sendCode(@RequestParam String phone){

        //首先在redis中查询缓存
        String value = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
        if(StringUtils.isNotEmpty(value)){
            long time= Long.parseLong(value.split("_")[1]);

            if(System.currentTimeMillis()-time<60000){
                return R.error(1001,"请求过于频繁");
            }
        }
        //TODO接口防刷

        String code ="1234";
        System.out.println("-----------------------------------------------------");
        System.out.println(phone);

        //将验证码缓存进Redis然后进行校验,防止手机再次发送验证码
        String redisCode=code+"_"+System.currentTimeMillis();
        redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,redisCode,10, TimeUnit.MINUTES);

//        smsFeign.sendCode(phone,code);
        log.info("--------{}-------{}-------",phone,code);
        return R.ok();
    }


    /**
     *  点击注册后model实现页面转发,导由于注册失败转发的url不变,此时再刷新页面,导致浏览器会将之前的请求重新发送
     *  导致表单重复提交,解决方案就是页面重定向,但是普通的重定向无法拿到之前请求域中的errors中的数据,导致信息无法显示在页面
     *  使用RedirectAttributes  这个类会在重定向的时候将请求域中的数据存储在session中,然后在下一个页面再取出session的数据
     *  取出成功,再删除session的数据;
     * /
    /**
     * 注册成功返回登录页面
     * @param userVo 用户注册输入数据
     * @param result 数据校验结果返回封装
     * @param redirectAttributes  模拟页面重定向,携带session数据
     * @return
     */
    @PostMapping("regist")
    public String backLogin(@Valid UserRegistVo userVo, BindingResult result, RedirectAttributes redirectAttributes){

        //校验出错,转发到注册页面
        if(result.hasErrors()){

            Map<String,String> errorMap=new HashMap<>();

            errorMap = result.getFieldErrors().stream().collect(Collectors.toMap(fieldError -> {
                return fieldError.getField();
            }, fieldError -> {
                return fieldError.getDefaultMessage();
            }));

            redirectAttributes.addFlashAttribute("errors",errorMap);

            return "redirect:http://auth.gulimail.com/reg.html";
        }

        //校验验证码
        String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + userVo.getPhone());
        if(StringUtils.isNotEmpty(redisCode)){
            String code =redisCode.split("_")[0];
            if(code.equals(userVo.getCode())){
                redisTemplate.delete(AuthServerConstant.SMS_CODE_CACHE_PREFIX+userVo.getPhone());

                //TODO 注册
                R r=memberFeign.regist(userVo);
                if(r.getCode()==0){
                    //成功
                    return "redirect:http://auth.gulimail.com/login.html";

                }else{
                    Map<String,String> errorMap=new HashMap<>();
                    errorMap.put("msg",r.getMsg());
                    return "redirect:http://auth.gulimail.com/reg.html";
                }
            }else {
                Map<String,String> errorMap=new HashMap<>();
                errorMap.put("code","验证码错误");
                return "redirect:http://auth.gulimail.com/reg.html";
            }
        }else {
            Map<String,String> errorMap=new HashMap<>();
            errorMap.put("code","验证码错误");
            return "redirect:http://auth.gulimail.com/reg.html";

        }

    }

}
